package com.jhc.drone.communication.network;


import com.jhc.drone.communication.enums.ProtocolEnum;
import com.jhc.drone.communication.network.udp.UdpClientInboundHandler;
import com.jhc.drone.communication.network.udp.UdpServerChannel;
import com.jhc.drone.communication.processor.MessageProcessorFactory;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.extern.slf4j.Slf4j;


/**
 * @author lcp
 * @date 2024年12月2024/12/30 13:58
 * @describe
 */
@Slf4j
public class UdpGateway extends Gateway {

    public static int PORT = 7901;
    protected final EventLoopGroup __bossGroup4Netty = new NioEventLoopGroup();
    protected final EventLoopGroup __workerGroup4Netty = new DefaultEventLoopGroup();
    protected Channel __serverChannel4Netty = null;
    protected ServerBootstrap bootstrap = null;
    protected MessageProcessorFactory droneUnpackHandler;

    public UdpGateway(MessageProcessorFactory object) {
        this.droneUnpackHandler = object;
        this.protocol = ProtocolEnum.UDP;
    }

    @Override
    public void init() {
        bootstrap = new ServerBootstrap()
                .group(__bossGroup4Netty, __workerGroup4Netty)
                .channel(UdpServerChannel.class)
                .childHandler(initChildChannelHandler(droneUnpackHandler));
    }

    @Override
    public void bind() throws Exception {
        ChannelFuture cf = bootstrap.bind("0.0.0.0", PORT).syncUninterruptibly();
        if (cf.isSuccess()) {
            log.info("[UDP服务绑定端口{}成功 √", PORT);
            timerTask();
        } else {
            log.info("UDP服务绑定端口{}失败 ×", PORT);
        }
        __serverChannel4Netty = cf.channel();
        __serverChannel4Netty.closeFuture().addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                __bossGroup4Netty.shutdownGracefully();
                __workerGroup4Netty.shutdownGracefully();
            }
        });

    }

    @Override
    public void shutdown() {
        if (__serverChannel4Netty != null)
            __serverChannel4Netty.close();
    }

    protected ChannelHandler initChildChannelHandler(final MessageProcessorFactory serverCoreHandler) {
        return new ChannelInitializer<Channel>() {
            @Override
            protected void initChannel(Channel channel) throws Exception {
                channel.pipeline()
                        .addLast(new ReadTimeoutHandler(SESSION_RECYCLER_EXPIRE))
                        .addLast(new UdpClientInboundHandler(serverCoreHandler, protocol));
            }
        };
    }
}
